package com.lm.activiti.personalTask;

import org.activiti.engine.IdentityService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricIdentityLink;
import org.activiti.engine.identity.Group;
import org.activiti.engine.impl.persistence.entity.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.junit.Test;

import java.io.InputStream;
import java.util.List;

/**
 * @author lm_jcf
 * @date 2018/5/8 14:37
 *
 * 角色组
 */
public class GroupUserTaskTest {

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    //    部署流程定义
    @Test
    public void deploymentProcessDefinition(){

        InputStream inputStreamBpmn = this.getClass().getResourceAsStream("groupUserTask.bpmn");

        Deployment deployment = processEngine.getRepositoryService()    //与流程定义和部署对象相关的额Service
                .createDeployment()     //创建一个部署对象
                .name("任务角色组")
//                .addClasspathResource("bpmn/processVariables.bpmn")    //加载资源dpmn
                .addInputStream("groupUserTask.bpmn", inputStreamBpmn)
                .deploy();   //完成部署

        System.out.println("流程Id"+deployment.getId());  //  3701
        System.out.println("流程名称"+deployment.getName());

        //部署时，添加用户角色组
        IdentityService i = processEngine.getIdentityService();
        //创建角色


        Group group = new GroupEntityImpl();
        group.setName("总经理");
        i.saveGroup(group);
        Group group2 = new GroupEntityImpl();
        group2.setName("部门经理");
        i.saveGroup(group2);
        //创建用户
        UserEntity userEntity = new UserEntityImpl();
        userEntity.setId("张三");
        userEntity.setPassword("12345");
        userEntity.setFirstName("花花");
        i.saveUser(userEntity);
        //建立用户和角色的关联关系
        i.createMembership("张三","部门经理");
        i.createMembership("李四","部门经理");
        i.createMembership("王五","总经理");
        System.out.println("添加组织机构成功");
    }


    // 启动流程定义
    @Test
    public void startProcessInstance(){
        String processKey = "groupUserTask";

        //启动流程实例的同时，，设置流程变量，使用流程变量用来指定办理人
        ProcessInstance pi = processEngine.getRuntimeService()      //与正在执行的流程实例和执行对象相关的Service
                .startProcessInstanceByKey(processKey);     //使用流程定义的Key启动流程实例，可以使之每次都启动最新版本的流程。
        System.out.println("流程实例ID："+pi.getId());
        System.out.println("流程定义ID："+pi.getProcessDefinitionId());

    }

    @Test
    public void deleteProcessInstance(){
        //得到repositoryService
        RepositoryService repositoryService = processEngine
                .getRepositoryService();
        //根据流程定义id查询部署id
        String processDefinitionId = "parallelGateWay:1:3704";
        ProcessDefinition processDefinition = repositoryService
                .createProcessDefinitionQuery()
                .processDefinitionId(processDefinitionId)
                .singleResult();
        //流程定义所属部署id
        String deploymentId = processDefinition.getDeploymentId();
        System.out.println("删除流程部署ID下的流程定义："+deploymentId);
        //1.根据流程部署id删除这一次部署的所有流程定义
        //建议一次部署只部署一个流程，根据流程部署id删除一个流程的定义
        //约束：如果该流程定义没有启动流程实例可以删除，如果该流程定义以及启动流程实例，不允许删除，如果删除就抛出异常
        repositoryService.deleteDeployment(deploymentId,true);
    }

    //查询当前人的组任务
    @Test
    public void findMyProcessTask() {
        String assignee = "李四";
        List<Task> lists = processEngine.getTaskService()  //与正在执行的任务相关的Service
                .createTaskQuery()  //创建任务查询对象
                /** 查询条件  */
//                .taskAssignee(assignee) //指定个人任务对象
                .taskCandidateUser(assignee) //组任务的办理人
                /** 排序*/
                .orderByTaskCreateTime().asc()  //使用创建时间升序排序
                /** 返回结果集*/
                .list();

        if (lists != null && lists.size() > 0) {
            for (Task task : lists) {
                System.out.println("任务ID:" + task.getId());
                System.out.println("任务名称:" + task.getName());
                System.out.println("任务创建时间:" + task.getCreateTime());
                System.out.println("任务办理人:" + task.getAssignee());
                System.out.println("流程实例ID:" + task.getProcessInstanceId());
                System.out.println("执行对象ID:" + task.getExecutionId());
                System.out.println("流程定义ID:" + task.getProcessDefinitionId());
            }
        }
    }

    //查询正在执行的任务办理人表
    @Test
    public void findPersionTask(){

        String taskId = "6004";

        List<IdentityLink> links =processEngine.getTaskService()
                .getIdentityLinksForTask(taskId);

        if (links != null && links.size() > 0) {
            for (IdentityLink link : links) {
                System.out.println(link.getTaskId() +" "+link.getType()+" "+link.getProcessInstanceId()+" "+link.getUserId());
            }

        }
    }

    //查询历史的任务办理人表
    @Test
    public void findHiPersionTask(){
        String processInstanceId = "6001";
        List<HistoricIdentityLink> list = processEngine.getHistoryService()
                                .getHistoricIdentityLinksForProcessInstance(processInstanceId);

        if (list != null && list.size() > 0) {
            for (HistoricIdentityLink link : list) {
                System.out.println(link.getTaskId() +" "+link.getType()+" "+link.getProcessInstanceId()+" "+link.getUserId());
            }
        }
    }

    //查询个人任务
    @Test
    public void findMyProcessTask2() {
        String assignee = "小白";
        List<Task> lists = processEngine.getTaskService()  //与正在执行的任务相关的Service
                .createTaskQuery()  //创建任务查询对象
                /** 查询条件  */
                .taskAssignee(assignee) //指定个人任务对象
//                .taskCandidateUser(taskCandidateUser) //组任务的办理人
//                .processDefinitionId()  //使用流程定义Id查询
//                .processInstanceId()    //使用流程实例ID
//                .executionId()  //使用执行对象id查询
                /** 排序*/
                .orderByTaskCreateTime().asc()  //使用创建时间升序排序
                /** 返回结果集*/
//                .singleResult()   //唯一结果集
//                .count()  //返回结果集的数量
//                .listPage()   //分页查询
                .list();

        if (lists != null && lists.size() > 0) {
            for (Task task : lists) {
                System.out.println("任务ID:" + task.getId());
                System.out.println("任务名称:" + task.getName());
                System.out.println("任务创建时间:" + task.getCreateTime());
                System.out.println("任务办理人:" + task.getAssignee());
                System.out.println("流程实例ID:" + task.getProcessInstanceId());
                System.out.println("执行对象ID:" + task.getExecutionId());
                System.out.println("流程定义ID:" + task.getProcessDefinitionId());
            }
        }
    }

    //拾取任务，将组任务分配给个人任务
    @Test
    public void claim(){
        String taskId = "6804";
        //分配的个人任务（可以是组任务中的成员，也可以是非组任务的成员）
        String userId = "张三";
        processEngine.getTaskService()
                .claim(taskId,userId);
    }

    //将个人任务回退到组任务，前提，之前一定是组任务
    @Test
    public void setAssigee(){
        String taskId = "6004";
        //分配的个人任务（可以是组任务中的成员，也可以是非组任务的成员）
        processEngine.getTaskService()
                .setAssignee(taskId,null);

    }

    //向组任务添加成员
    @Test
    public void addGroupUser(){
        String taskId = "6004";
        String userId = "小王";
        processEngine.getTaskService()
                .addCandidateUser(taskId,userId);
    }

    //向组任务删除成员
    @Test
    public void delGroupUser(){
        String taskId = "6004";
        String userId = "小王";
        processEngine.getTaskService()
                .deleteCandidateUser(taskId,userId);
    }

    @Test
    public void completeMyProcessTask(){
        String taskId = "1804  ";
        processEngine.getTaskService()
                .complete(taskId);
        System.out.println("完成任务");

    }
}
